package com.advert.provider.advert;

import com.advert.model.advert.AdvertEntity;
import com.advert.model.advert.search.*;
import com.advert.model.security.AccessMode;
import com.advert.model.security.Status;
import com.advert.model.vehicle.VehicleEntity;
import com.advert.provider.ProviderBase;
import com.advert.util.Event;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.core.Events;

import javax.persistence.Query;
import java.util.List;


@Name("AdvertProvider")
@Scope(ScopeType.EVENT)
@AutoCreate
public class AdvertProvider extends ProviderBase {

    public AdvertEntity createAdvert(AdvertEntity advertEntity) {
        Events.instance().raiseEvent(Event.ENTITY_ACCESS, advertEntity, AccessMode.ADD);

        entityManager.persist(advertEntity);
        return advertEntity;
    }

    public AdvertEntity updateAdvert(AdvertEntity advert) {
        Events.instance().raiseEvent(Event.ENTITY_ACCESS, advert, AccessMode.EDIT);

        return entityManager.merge(advert);
    }

    public void removeAdvert(AdvertEntity advert) {
        Events.instance().raiseEvent(Event.ENTITY_ACCESS, advert, AccessMode.DELETE);

        entityManager.remove(advert);
    }

    public VehicleEntity updateVehicle(VehicleEntity vehicle) {
        Events.instance().raiseEvent(Event.ENTITY_ACCESS, vehicle, AccessMode.EDIT);

        return entityManager.merge(vehicle);
    }

    @SuppressWarnings("unchecked")
    public List<AdvertEntity> getAdverts(CriteriaBase criteria) {
        Query q = buildAdvertsQuery(criteria);
        q.setFirstResult(criteria.getFirstIndex());
        q.setMaxResults(criteria.getCount());
        return q.getResultList();
    }

    public long getAdvertsCount(CriteriaBase criteria) {
        return (Long)buildCountQuery(criteria).getSingleResult();
    }

    public AdvertEntity getAdvert(Integer advertId) {
        return entityManager.find(AdvertEntity.class, advertId);
    }


    private Query buildAdvertsQuery(CriteriaBase criteria) {
        Query q = null;
        if (criteria instanceof VehicleCategoryCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getByTypeAndProductTypeAndVehicleCategory");
            q.setParameter("type", ((VehicleCategoryCriteria)criteria).getAdvertType());
            q.setParameter("productType", ((VehicleCategoryCriteria)criteria).getProductType());
            q.setParameter("vehicleCategory", ((VehicleCategoryCriteria)criteria).getVehicleCategoryCd());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof VehicleTypeCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getByTypeAndProductTypeAndVehicleType");
            q.setParameter("type", ((VehicleTypeCriteria)criteria).getAdvertType());
            q.setParameter("productType", ((VehicleTypeCriteria)criteria).getProductType());
            q.setParameter("vehicleType", ((VehicleTypeCriteria)criteria).getVehicleTypeCd());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof ProductTypeCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getByTypeAndProductType");
            q.setParameter("type", ((ProductTypeCriteria)criteria).getAdvertType());
            q.setParameter("productType", ((ProductTypeCriteria)criteria).getProductType());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof AdvertTypeCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getByType");
            q.setParameter("type", ((AdvertTypeCriteria)criteria).getAdvertType());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof OwnerIdCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getByOwnerId");
            q.setParameter("ownerId", ((OwnerIdCriteria)criteria).getOwnerId());
        } else if (criteria instanceof AdvertStatusCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getByStatus");
            q.setParameter("status", ((AdvertStatusCriteria)criteria).getStatus());
        }
        return q;
    }

    private Query buildCountQuery(CriteriaBase criteria) {
        Query q = null;
        if (criteria instanceof VehicleCategoryCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getCountByTypeAndProductTypeAndVehicleCategory");
            q.setParameter("type", ((VehicleCategoryCriteria)criteria).getAdvertType());
            q.setParameter("productType", ((VehicleCategoryCriteria)criteria).getProductType());
            q.setParameter("vehicleCategory", ((VehicleCategoryCriteria)criteria).getVehicleCategoryCd());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof VehicleTypeCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getCountByTypeAndProductTypeAndVehicleType");
            q.setParameter("type", ((VehicleTypeCriteria)criteria).getAdvertType());
            q.setParameter("productType", ((VehicleTypeCriteria)criteria).getProductType());
            q.setParameter("vehicleType", ((VehicleTypeCriteria)criteria).getVehicleTypeCd());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof ProductTypeCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getCountByTypeAndProductType");
            q.setParameter("type", ((ProductTypeCriteria)criteria).getAdvertType());
            q.setParameter("productType", ((ProductTypeCriteria)criteria).getProductType());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof AdvertTypeCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getCountByType");
            q.setParameter("type", ((AdvertTypeCriteria)criteria).getAdvertType());
            q.setParameter("status", Status.APPROVED);
        } else if (criteria instanceof OwnerIdCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getCountByOwnerId");
            q.setParameter("ownerId", ((OwnerIdCriteria)criteria).getOwnerId());
        } else if (criteria instanceof AdvertStatusCriteria) {
            q = entityManager.createNamedQuery("AdvertEntity.getCountByStatus");
            q.setParameter("status", ((AdvertStatusCriteria)criteria).getStatus());
        }
        return q;
    }
}
